﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Logika
{
    public class Snake
    {
        private int size;

        public List<SnakePart> snakeBody = new List<SnakePart>();

        private MOVINGDIRECTION direction;
        private Point startingPoint;
        private Point currentPosition;
        private bool alive;

        public List<SnakePart> getSnakeBody()
        {
            return snakeBody;
        }

        public void addPart(int x, int y)
        {
            snakeBody.Add(new SnakePart(x, y));
        }

        public enum MOVINGDIRECTION 
        {
            UPWARDS = 8,
            DOWNWARDS = 2,
            TOLEFT = 4,
            TORIGHT = 6
        };

        public void setAlive(bool alive)
        {
            this.alive = alive;
        }

        public bool getAlive()
        {
            return alive;
        }

        public void povecajKaco(int v)
        {
            size += v;
        }

        public void odstraniRep()
        {
            snakeBody.RemoveAt(0);
        }

        public int getSize()
        {
            return size;
        }

        public Snake() 
        {
            CalcSpawnPosition(0);
            direction = MOVINGDIRECTION.UPWARDS;
            size = 5;
            alive = true;
        }

        public void setDirection(int ndirection)
        {
            MOVINGDIRECTION newDirection = (MOVINGDIRECTION) ndirection;
            if (newDirection == MOVINGDIRECTION.TOLEFT && direction != MOVINGDIRECTION.TORIGHT ||
                newDirection == MOVINGDIRECTION.TORIGHT && direction != MOVINGDIRECTION.TOLEFT ||
                newDirection == MOVINGDIRECTION.UPWARDS && direction != MOVINGDIRECTION.DOWNWARDS ||
                newDirection == MOVINGDIRECTION.DOWNWARDS && direction != MOVINGDIRECTION.UPWARDS)
            this.direction = newDirection;
        }

        public int getDirection()
        {
            return (int)direction;
        }

        public bool move(NarediSobo soba, Snake s)
        {
            SnakePart newPart = new SnakePart();
            newPart.X = snakeBody[snakeBody.Count - 1].X;
            newPart.Y = snakeBody[snakeBody.Count - 1].Y;
            if (direction == MOVINGDIRECTION.UPWARDS)
            {
                newPart.Y = newPart.Y - 1;
            }
            else if (direction == MOVINGDIRECTION.DOWNWARDS)
            {
                newPart.Y = newPart.Y + 1;
            }
            else if (direction == MOVINGDIRECTION.TOLEFT)
            {
                newPart.X = newPart.X - 1;
            }
            else if (direction == MOVINGDIRECTION.TORIGHT)
            {
                newPart.X = newPart.X + 1;
            }
            if (collisionBody(newPart) || collisionMap(newPart, soba) || collisionOtherSnakes(newPart, s))
            {
                return false;
            }
            snakeBody.Add(newPart);
            if (snakeBody.Count > size)
                odstraniRep();
            return true;
        }

        public bool kacaMrtva()
        {
            return !(size > 0);
        }

        public bool collisionOtherSnakes(SnakePart newPart, Snake s)
        {
            for (int i = 0; i < s.snakeBody.Count; i++)
            {
                if (newPart.X == s.snakeBody[i].X && newPart.Y == s.snakeBody[i].Y)
                {
                    return true;
                }
            }
            return false;
        }

        public bool collisionMap(SnakePart newPart, NarediSobo soba)
        {
            for (int i = 0; i < soba.tocke.Count; i++)
            {
                if (newPart.X == soba.tocke[i][0] / 20 && newPart.Y == soba.tocke[i][1] / 20)
                {
                    return true;
                }
            }
            return false;
        }

        public void CalcSpawnPosition(int bottomBorderY) 
        {
            startingPoint = new Point(0, bottomBorderY);
            currentPosition = startingPoint;
        }

        public bool collisionBody(SnakePart p)
        {
            for (int i = 0; i < snakeBody.Count; i++)
            {
                if (p.X == snakeBody[i].X && p.Y == snakeBody[i].Y)
                {
                    return true;
                }
            }
            return false;
        }

        /*public bool CollisionBody() 
        {
            for (int q = 0; q < (snakeBody.Count - size * 2); q++)
            {
                Point point = new Point(snakeBody[q].X, snakeBody[q].Y);
                if ((Math.Abs(point.X - currentPosition.X) < (size)) &&
                     (Math.Abs(point.Y - currentPosition.Y) < (size)))
                {
                    return true;
                }

            }
            return false;
        }

        public bool CollisionBody(Snake _snake)
        {
            for (int q = 0; q < _snake.snakeBody.Count; q++)
            {
                Point point = new Point(_snake.snakeBody[q].X, _snake.snakeBody[q].Y);
                if ((Math.Abs(point.X - currentPosition.X) < (_snake.size)) &&
                     (Math.Abs(point.Y - currentPosition.Y) < (_snake.size)))
                {
                    return true;
                }

            }

            return false;
        }*/
    }
}
